﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Reborn_Server.App1AppHandler;
using System.Threading;
using Reborn_WorldServer.App1AppHandler;

namespace App1AppHandler
{
    public class Map
    {
        public AppHandler2 GameHandler;
        public List<MapItem> MapItems = new List<MapItem>();

        private int _MapID = -1;
        public int MapID
        {
            set
            {
                _MapID = value;

                if (_MapInstance != -1)
                    this.mapJobsThread.Name = "Map Thread (" + _MapID.ToString() + "," + _MapInstance.ToString() + ")";
            }
            get
            {
                return _MapID;
            }
        }

        private int _MapInstance = -1;
        public int MapInstance
        {
            set
            {
                _MapInstance = value;

                if (_MapID != -1)
                    this.mapJobsThread.Name = "Map Thread (" + _MapID.ToString() + "," + _MapInstance.ToString() + ")";
            }
            get
            {
                return _MapInstance;
            }
        }



        public int StartMapID = -1;
        public int StartMapX = -1;
        public int StartMapY = -1;

        public int numCreatures = 0;

        public volatile LootManager LootMngr;

        private List<Vendor> Vendors = new List<Vendor>();
        private List<Trainer> Trainers = new List<Trainer>();

        private List<CreatureBase> creaturesToProcess = new List<CreatureBase>();
        public void addCreatureToProcess(CreatureBase creature)
        {
            lock (creaturesToProcess)
            {
                creaturesToProcess.Add(creature);
            }
        }
        public void removeCreatureToProcess(CreatureBase creature)
        {
            lock (creaturesToProcess)
            {
                creaturesToProcess.Remove(creature);
            }
        }
        public Creature findCreatureToProcessByDbId(int id)
        {
            lock (creaturesToProcess)
            {
                foreach (CreatureBase creatureBase in creaturesToProcess)
                {
                    if (creatureBase is Creature)
                    {
                        Creature creature = (Creature)creatureBase;
                        if (creature.ID == id)
                            return creature;
                    }
                }
            }
            return null;
        }

        private Thread mapJobsThread;

        public Map(AppHandler2 gameHandler) 
        {
            Map map = this;

            GameHandler = gameHandler;
            LootMngr = new LootManager(map);

            mapJobsThread = new Thread(this.runMapJobs);
            mapJobsThread.IsBackground = true;
            mapJobsThread.Start();
        }

        public Vendor getVendor(long CreatureGUID)
        {
            foreach (Vendor vendor in Vendors)
            {
                if (vendor.CreatureID == CreatureGUID)
                    return vendor;
            }
            return null;
        }
        public void addVendor(Vendor vendor)
        {
            Vendors.Add(vendor);
        }

        public Trainer getTrainer(long CreatureGUID)
        {
            foreach (Trainer trainer in Trainers)
            {
                if (trainer.CreatureID == CreatureGUID)
                    return trainer;
            }
            return null;
        }
        public void addTrainer(Trainer trainer)
        {
            Trainers.Add(trainer);
        }


        private void runMapJobs()
        {
            while (true)
            {
                CreatureBase creatureToProcess = null;

                bool runRegen = false;
                bool runAI = false;

                lock (creaturesToProcess)
                {
                    foreach (CreatureBase creatureBase in creaturesToProcess)
                    {
                        runRegen = creatureBase.Timer_Regen.timerExpired;
                        if (creatureBase is Creature)
                        {
                            Creature creature = (Creature)creatureBase;
                            runAI = creature.creatureAI.Timer_CreatureRound.timerExpired;
                        }
                        if (runRegen || runAI)
                        {
                            creatureToProcess = creatureBase;
                            break;
                        }
                    }
                }

                if (runAI == false && runRegen == false)
                {
                    System.Threading.Thread.Sleep(25);
                }
                else
                {
                    try
                    {
                        if (runRegen)
                            creatureToProcess.runRegen();

                        if (runAI)
                        {
                            Creature creature = (Creature)creatureToProcess;
                            creature.runAI();
                        }
                    }
                    catch (Exception ex)
                    {
                        int x = 0;
                    }
                }

            }//Loop
        }


        public List<MapItem> GetMapItemsWithin(int mapX, int mapY, int distance)
        {
            List<MapItem> result = new List<MapItem>();
            foreach (MapItem mapitem in MapItems)
            {
                if (Math.Abs(mapitem.MapX - mapX) <= 4 && Math.Abs(mapitem.MapY - mapY) <= 4)
                    result.Add(mapitem);
            }
            return result;
        }

        public MapItem GetMapItem(int mapX, int MapY)
        {
            foreach (MapItem mapitem in MapItems)
            {
                if (mapitem.MapX == mapX && mapitem.MapY == MapY)
                    return mapitem;
            }
            return null;
        }
    }

}
